package com.Alibaba;

import android.app.Activity;
import android.app.Application;
import android.util.Log;
import android.webkit.WebChromeClient;
import android.webkit.WebViewClient;
import android.widget.Toast;

import com.ali.auth.third.core.model.Session;
import com.alibaba.baichuan.android.trade.AlibcTrade;
import com.alibaba.baichuan.android.trade.AlibcTradeSDK;
import com.alibaba.baichuan.android.trade.callback.AlibcTradeCallback;
import com.alibaba.baichuan.android.trade.callback.AlibcTradeInitCallback;
import com.alibaba.baichuan.android.trade.model.AlibcShowParams;
import com.alibaba.baichuan.android.trade.model.OpenType;
import com.alibaba.baichuan.android.trade.page.AlibcAddCartPage;
import com.alibaba.baichuan.android.trade.page.AlibcBasePage;
import com.alibaba.baichuan.android.trade.page.AlibcDetailPage;
import com.alibaba.baichuan.android.trade.page.AlibcMyCartsPage;
import com.alibaba.baichuan.android.trade.page.AlibcMyOrdersPage;
import com.alibaba.baichuan.android.trade.page.AlibcShopPage;
import com.alibaba.baichuan.trade.biz.AlibcConstants;
import com.alibaba.baichuan.trade.biz.applink.adapter.AlibcFailModeType;
import com.alibaba.baichuan.trade.biz.context.AlibcResultType;
import com.alibaba.baichuan.trade.biz.context.AlibcTradeResult;
import com.alibaba.baichuan.trade.biz.core.taoke.AlibcTaokeParams;
import com.alibaba.baichuan.trade.biz.login.AlibcLogin;
import com.alibaba.baichuan.trade.biz.login.AlibcLoginCallback;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.chen.xiaotaoliangmeng.MainActivity;

import java.util.Map;
import java.util.HashMap;

public class AlibabaModule extends ReactContextBaseJavaModule  {
    private final ReactApplicationContext reactContext;

    private final static int SuccessCode = 0;  //成功
    private final static int FailCode = -1;    //失败


    public AlibabaModule(ReactApplicationContext context) {
        super(context);
        reactContext = context;
    }

    // ReactContextBaseJavaModule要求派生类实现getName方法。这个函数用于返回一个字符串名字，这个名字在 JavaScript 端标记这个模块
    @Override
    public String getName() {
        return "AlibabaSdk";
    }


    // 要导出一个方法给 JavaScript 使用，Java 方法需要使用注解@ReactMethod。方法的返回类型必须为void。React Native 的跨语言访问是异步进行的
    @ReactMethod
    public void show(String message, int duration,Callback callback) {
        Log.i("ttt","sssss");
        callback.invoke("成功回调!");
    }

    /**
     * 初始化
     */
    @ReactMethod
    public  void  asyncInit(final Callback callback){
        Print("-------------------asyncInit---------------------");
        AlibcTradeSDK.asyncInit((Application) reactContext.getApplicationContext(), new AlibcTradeInitCallback() {
            @Override
            public void onSuccess() {
                Print("-------------------初始化成功---------------------");
                WritableMap map = Arguments.createMap();
                map.putInt("code", 1);
                map.putString("msg", "初始化成功");
                callback.invoke(SuccessCode,map);
            }

            @Override
            public void onFailure(int code, String msg) {
                Print("-------------------初始化失败---------------------");
                WritableMap map = Arguments.createMap();
                map.putInt("code", code);
                map.putString("msg", msg);
                callback.invoke(FailCode,map);
            }
        });
    }

    /**
     * 登录
     */
    @ReactMethod
    public void showLogin(final Callback callback) {
        Print("====================showLogin========================");
        AlibcLogin alibcLogin = AlibcLogin.getInstance();
        alibcLogin.showLogin(new AlibcLoginCallback() {
            @Override
            public void onSuccess(int result, String userId, String nick) {
                Print("====================登录成功========================");
                Session session = AlibcLogin.getInstance().getSession();
                WritableMap map = Arguments.createMap();
                map.putString("nick", session.nick);
                map.putString("avatarUrl", session.avatarUrl);
                map.putString("openId", session.openId);
                callback.invoke(SuccessCode, map);
            }

            @Override
            public void onFailure(int code, String msg) {
                Print("====================登录失败========================");
                WritableMap map = Arguments.createMap();
                map.putInt("code", code);
                map.putString("msg", msg);
                callback.invoke(FailCode,map);
            }
        });

    }

    /**
     * 是否登录
     */
    @ReactMethod
    public void isLogin(final Callback callback) {
        callback.invoke(SuccessCode, AlibcLogin.getInstance().isLogin());
    }

    /**
     * 获取已登录的用户信息---无参数传入
     */
    @ReactMethod
    public void getUserInfo(final Callback callback) {
        if (AlibcLogin.getInstance().isLogin()) {
            Session session = AlibcLogin.getInstance().getSession();
            WritableMap map = Arguments.createMap();
            map.putString("nick", session.nick);
            map.putString("avatarUrl", session.avatarUrl);
            map.putString("openId", session.openId);
            callback.invoke(SuccessCode, map);
        } else {
            callback.invoke(FailCode,"");
        }
    }

    /**
     * 退出登录---无参数传入
     */
    @ReactMethod
    public void logout(final Callback callback) {

        AlibcLogin alibcLogin = AlibcLogin.getInstance();

        alibcLogin.logout(new AlibcLoginCallback() {

            @Override
            public void onSuccess(int code, String s, String s1) {
                WritableMap map = Arguments.createMap();
                map.putInt("code",code);
                map.putString("s",s);
                map.putString("s1",s1);
                callback.invoke(SuccessCode, map);
            }

            @Override
            public void onFailure(int code, String s) {
                WritableMap map = Arguments.createMap();
                map.putInt("code",code);
                map.putString("s",s);
                callback.invoke(FailCode, map);
            }
        });
    }

    /**
     * 展示
     */
    @ReactMethod
    public void  showPage(final ReadableMap param,final Callback callback){
        String type = param.getString("type");
        ReadableMap payload = param.getMap("payload");
        switch (type) {
            case "detail":  //详情页
                Print("===========detail================");
                this.openByBizCode(new AlibcDetailPage(payload.getString("itemid")), param, callback);
                break;
            case "url":      //url 方式
                Print("===========url================");
                this.openByUrl(param,   payload.getString("url"),callback);
                break;
            case "shop":      //商店
                Print("===========shop================");
                this.openByBizCode(new AlibcShopPage(payload.getString("shopid")), param, callback);
                break;
            case "orders":     //我的订单页(测试发现都会跳到我的购物车===>mycard)
                Print("===========orders================");
                //{"all 0", "waitPay 1", "waitSend 2", "waitConfirm 3", "waitRate 4"};
                this.openByBizCode(new AlibcMyOrdersPage(payload.getInt("orderStatus"), payload.getBoolean("allOrder")), param, callback);
                break;
            case "addCard":    //添加购物车(测试发现都会跳到我的购物车===>mycard)
                Print("===========addCard================");
                this.openByBizCode(new AlibcAddCartPage(payload.getString("itemid")), param, callback);
                break;
            case "mycard":     //我的购物车
                Print("===========mycard================");
                this.openByBizCode(new AlibcMyCartsPage(), param, callback);
                break;
            default:
                callback.invoke(FailCode,null);
                break;
        }
    }

    private void openByBizCode(AlibcBasePage page, final ReadableMap param, final Callback callback) {
        // 处理参数
        AlibcShowParams showParams = this.dealShowParams(param);
        AlibcTaokeParams taokeParams = this.dealTaokeParams(param);
        Map<String, String> exParams = this.dealExParams(param);
        ReadableMap payload = param.getMap("payload");
        String BizCodeStr = "";  // detail  shop cart(购物车)
        if (payload.getString("BizCodeStr") != null && !payload.getString("BizCodeStr").equals("")) {
            BizCodeStr = payload.getString("BizCodeStr");
        }

        AlibcTrade.openByBizCode(getCurrentActivity(), page, null, new WebViewClient(),new WebChromeClient(), BizCodeStr,
                showParams, taokeParams,exParams,createAlibcTradeCallback(callback));
    }

    private void openByUrl(final ReadableMap param,String url, final Callback callback){
        AlibcShowParams showParams = this.dealShowParams(param);
        AlibcTaokeParams taokeParams = this.dealTaokeParams(param);
        Map<String, String> exParams = this.dealExParams(param);
        // 通过百川内部的webview打开页面
        AlibcTrade.openByUrl(getCurrentActivity(), "", url, null,
                new WebViewClient(), new WebChromeClient(),
                showParams, taokeParams, exParams, createAlibcTradeCallback(callback));
    }



    /**
     * 处理showParams公用参数
     */
    private  AlibcShowParams dealShowParams(final ReadableMap param){
        ReadableMap payload = param.getMap("payload");
        AlibcShowParams showParams = new AlibcShowParams();

        String _OpenType = payload.getString("OpenType");
        String _clientType = payload.getString("clientType");
        String _BACK_URL = payload.getString("BACK_URL");
        String _AlibcFailModeType = payload.getString("AlibcFailModeType");

       // OpenType ：Native表示唤端，Auto表示不做设置
        if (_OpenType != null && !_OpenType.equals("")) {
            if (_OpenType.equals("Auto")){
                showParams.setOpenType(OpenType.Auto);
            }
            if (_OpenType.equals("Native")){
                showParams.setOpenType(OpenType.Native);
            }
        }

        // clientType ：taobao---唤起淘宝客户端；tmall ---唤起天猫客户端
        if (_clientType != null && !_clientType.equals("")) {
            if (_clientType.equals("taobao") || _clientType.equals("tmall"))
                showParams.setClientType(_clientType);
        }

        // BACK_URL :（小把手）：唤端返回的scheme (如果不传默认将不展示小把手；如果想展示小把手，可以自己传入自定义的scheme，或者传入百川提供的默认scheme："alisdk://")
        if (_BACK_URL != null && !_BACK_URL.equals("")) {
                showParams.setBackUrl(_BACK_URL);
        }

        // clientType ：taobao---唤起淘宝客户端；tmall---唤起天猫客户端
        if (_AlibcFailModeType != null && !_AlibcFailModeType.equals("")) {
            showParams.setNativeOpenFailedMode(getAlibcFailModeType(_AlibcFailModeType));
        }

        return showParams;
    }

    /**
     * 处理taokeParams公用参数
     */
    private AlibcTaokeParams dealTaokeParams(final ReadableMap param) {
        ReadableMap payload = param.getMap("payload");

        AlibcTaokeParams taokeParams = new AlibcTaokeParams("", "", "");
        Map<String, String> taokeExParams = new HashMap<String, String>();

        // 初始化参数
        String pid = "mm_23448739_6500158_22182062";
        String adzoneid = "60538822";
        String tkkey = "23482513";
        String sellerId = "";

        // 设置mmpid
        if (payload.getString("Pid") != null
                && !payload.getString("Pid").equals("")) {
            pid = payload.getString("Pid");
        }

        //注：1、如果走adzoneId的方式分佣打点，需要在extraParams中显式传入taokeAppkey，否则打点失败；
        //  2、如果是打开店铺页面(shop)，需要在extraParams中显式传入sellerId，否则同步打点转链失败）
        // 设置adzoneid
        if (payload.getString("Adzoneid") != null
                && !payload.getString("Adzoneid").equals("")) {
            adzoneid = payload.getString("Adzoneid");
        }

        // 设置taokeAppkey
        if (payload.getString("taokeAppkey") != null
                && !payload.getString("taokeAppkey").equals("")) {
            tkkey = payload.getString("taokeAppkey");
        }

        // 设置sellerId
        if (payload.getString("sellerId") != null
                && !payload.getString("sellerId").equals("")) {
            sellerId = payload.getString("sellerId");
            taokeExParams.put("sellerId", sellerId);
        }

        taokeParams.setPid(pid);
        taokeParams.setAdzoneid(adzoneid);
        taokeExParams.put("taokeAppkey", tkkey);
        taokeParams.extraParams = taokeExParams;
        return taokeParams;
    }

    /**
     * 处理exParams公用参数
     */
    private Map<String, String> dealExParams(final ReadableMap param) {
        ReadableMap payload = param.getMap("payload");
        // 初始化参数
        Map<String, String> exParams = new HashMap<String, String>();
        String isvcode = "app";
        // 设置tkkey
        if (payload.getString("isvcode") != null
                || !payload.getString("isvcode").equals("")) {
            isvcode = payload.getString("isvcode");
        }
        exParams.put(AlibcConstants.ISV_CODE, isvcode);
        return exParams;
    }

    /*
     * AlibcFailModeType（唤端失败模式） :  
     * AlibcNativeFailModeNONE：不做处理；
       AlibcNativeFailModeJumpBROWER：跳转浏览器；
       AlibcNativeFailModeJumpDOWNLOAD：跳转下载页；
       AlibcNativeFailModeJumpH5：应用内webview打开）
       注：AlibcNativeFailModeJumpBROWER 不推荐使用）
     * */
    private AlibcFailModeType getAlibcFailModeType(String mode){

        AlibcFailModeType nativeOpenFailedMode = AlibcFailModeType.AlibcNativeFailModeJumpH5;
        switch (mode){
            case "AlibcNativeFailModeNONE":
                nativeOpenFailedMode = AlibcFailModeType.AlibcNativeFailModeNONE;break;
            case "AlibcNativeFailModeJumpBROWER":
                nativeOpenFailedMode = AlibcFailModeType.AlibcNativeFailModeJumpBROWER;break;
            case "AlibcNativeFailModeJumpDOWNLOAD":
                nativeOpenFailedMode = AlibcFailModeType.AlibcNativeFailModeJumpDOWNLOAD;break;
            case "AlibcNativeFailModeJumpH5":
                nativeOpenFailedMode = AlibcFailModeType.AlibcNativeFailModeJumpH5;break;
            default:
                nativeOpenFailedMode = AlibcFailModeType.AlibcNativeFailModeJumpH5;
                break;
        }
        return  nativeOpenFailedMode;
    }

    private AlibcTradeCallback createAlibcTradeCallback(final Callback callback){
        return new AlibcTradeCallback() {
            @Override
            public void onTradeSuccess(AlibcTradeResult alibcTradeResult) {
                //打开电商组件，用户操作中成功信息回调。tradeResult：成功信息（结果类型：加购，支付；支付结果）
                if (alibcTradeResult.resultType.equals(AlibcResultType.TYPECART)) {
                    //加购成功
                    Print("=================加购成功===============");
                    WritableMap map = Arguments.createMap();
                    map.putString("type", "card");
                    callback.invoke(SuccessCode, map);
                } else if (alibcTradeResult.resultType.equals(AlibcResultType.TYPEPAY)) {
                    //支付成功
                    Print("=================支付成功===============");
                    WritableMap map = Arguments.createMap();
                    map.putString("type", "pay");
                    map.putString("orders", "" + alibcTradeResult.payResult.paySuccessOrders);
                    callback.invoke(SuccessCode, map);
                } else {
                    Print("=================show成功===============");
                    callback.invoke(SuccessCode,null);
                }
            }

            @Override
            public void onFailure(int code, String msg) {
                Print("=================show失败===============");
                Print(msg);
                WritableMap map = Arguments.createMap();
                map.putString("type", "error");
                map.putInt("code", code);
                map.putString("msg", msg);
                callback.invoke(FailCode,map);
            }
        };
    }

    private void  Print(String msg){
        Log.i("Alibc",msg);
    }
}
